package view.student;

import controller.AttendanceController;
import model.AttendanceRecord;
import model.CreditLog;
import model.User;
import dao.AttendanceDAO.CheckInResult;
import dao.AttendanceDAO.CheckOutResult;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.swing.Timer;

/**
 * 现代化考勤签到面板
 */
public class AttendancePanel extends JPanel {
    private User currentUser;
    private AttendanceController attendanceController;

    private JPanel todayAttendancePanel;
    private JPanel attendanceHistoryPanel;

    // 筛选组件
    private JComboBox<String> todayStatusFilter;
    private JComboBox<String> historyStatusFilter;
    private List<AttendanceRecord> todayRecords;
    private List<AttendanceRecord> historyRecords;

    public AttendancePanel(User user) {
        this.currentUser = user;
        this.attendanceController = new AttendanceController();

        initComponents();
        setupLayout();
        loadData();

        // 设置定时器，每30秒刷新一次今日考勤状态
        Timer refreshTimer = new Timer(30000, e -> loadTodayAttendance());
        refreshTimer.start();
    }

    private void initComponents() {
        setLayout(new BorderLayout());
        setBackground(new Color(247, 250, 255));

        todayAttendancePanel = new JPanel();
        attendanceHistoryPanel = new JPanel();
    }

    private void setupLayout() {
        // 现代化顶部控制栏
        JPanel controlPanel = createModernControlPanel();
        add(controlPanel, BorderLayout.NORTH);

        // 主要内容区域
        JPanel mainPanel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                // 渐变背景
                GradientPaint gradient = new GradientPaint(
                        0, 0, new Color(247, 250, 255),
                        0, getHeight(), new Color(240, 245, 255));
                g2d.setPaint(gradient);
                g2d.fillRect(0, 0, getWidth(), getHeight());
            }
        };

        mainPanel.setLayout(new BorderLayout(0, 20));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(30, 30, 30, 30));

        // 今日考勤状态卡片
        JPanel todayCard = createTodayAttendanceCard();

        // 最近考勤历史卡片
        JPanel historyCard = createAttendanceHistoryCard();

        // 使用2列布局
        JPanel contentGrid = new JPanel(new GridLayout(1, 2, 20, 0));
        contentGrid.setOpaque(false);
        contentGrid.add(todayCard);
        contentGrid.add(historyCard);

        mainPanel.add(contentGrid, BorderLayout.CENTER);

        add(mainPanel, BorderLayout.CENTER);
    }

    private JPanel createModernControlPanel() {
        JPanel panel = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                // 渐变背景
                GradientPaint gradient = new GradientPaint(0, 0, Color.WHITE, 0, getHeight(), new Color(248, 252, 255));
                g2d.setPaint(gradient);
                g2d.fillRect(0, 0, getWidth(), getHeight());

                // 底部分割线
                g2d.setColor(new Color(226, 232, 240));
                g2d.drawLine(0, getHeight() - 1, getWidth(), getHeight() - 1);
            }
        };

        panel.setLayout(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(25, 30, 25, 30));

        // 左侧：标题和描述
        JPanel leftPanel = new JPanel(new BorderLayout());
        leftPanel.setOpaque(false);

        JLabel titleLabel = new JLabel("考勤签到中心");
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 24));
        titleLabel.setForeground(new Color(30, 41, 59));

        JLabel subLabel = new JLabel("管理您的签到签退和查看考勤记录");
        subLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        subLabel.setForeground(new Color(100, 116, 139));

        leftPanel.add(titleLabel, BorderLayout.NORTH);
        leftPanel.add(subLabel, BorderLayout.CENTER);

        // 右侧：刷新按钮
        JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
        rightPanel.setOpaque(false);

        JButton refreshButton = new JButton("刷新状态");
        styleModernButton(refreshButton, new Color(99, 102, 241));
        refreshButton.addActionListener(e -> loadData());
        rightPanel.add(refreshButton);

        panel.add(leftPanel, BorderLayout.WEST);
        panel.add(rightPanel, BorderLayout.EAST);

        return panel;
    }

    private JPanel createTodayAttendanceCard() {
        JPanel card = createModernCard();
        card.setLayout(new BorderLayout(0, 15));

        // 卡片标题和筛选
        JPanel headerPanel = new JPanel(new BorderLayout());
        headerPanel.setOpaque(false);

        // 左侧标题
        JPanel titleContainer = new JPanel(new BorderLayout());
        titleContainer.setOpaque(false);

        JLabel titleLabel = new JLabel("今日考勤状态");
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
        titleLabel.setForeground(new Color(30, 41, 59));

        JLabel descLabel = new JLabel("查看今天的预约，进行签到签退操作");
        descLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        descLabel.setForeground(new Color(100, 116, 139));

        titleContainer.add(titleLabel, BorderLayout.NORTH);
        titleContainer.add(descLabel, BorderLayout.CENTER);

        // 右侧筛选器
        JPanel filterPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
        filterPanel.setOpaque(false);

        JLabel filterLabel = new JLabel("状态筛选：");
        filterLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        filterLabel.setForeground(new Color(100, 116, 139));

        todayStatusFilter = new JComboBox<>(new String[] {
                "全部", "待签到", "已签到", "已完成", "超时违规", "未开始"
        });
        todayStatusFilter.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        todayStatusFilter.setPreferredSize(new Dimension(100, 28));

        // 添加筛选事件
        todayStatusFilter.addActionListener(e -> filterTodayRecords());

        filterPanel.add(filterLabel);
        filterPanel.add(Box.createHorizontalStrut(5));
        filterPanel.add(todayStatusFilter);

        headerPanel.add(titleContainer, BorderLayout.WEST);
        headerPanel.add(filterPanel, BorderLayout.EAST);

        // 内容区域
        todayAttendancePanel.setOpaque(false);
        todayAttendancePanel.setLayout(new BoxLayout(todayAttendancePanel, BoxLayout.Y_AXIS));

        JScrollPane scrollPane = new JScrollPane(todayAttendancePanel);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        scrollPane.setOpaque(false);
        scrollPane.getViewport().setOpaque(false);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        card.add(headerPanel, BorderLayout.NORTH);
        card.add(scrollPane, BorderLayout.CENTER);

        return card;
    }

    private JPanel createAttendanceHistoryCard() {
        JPanel card = createModernCard();
        card.setLayout(new BorderLayout(0, 15));

        // 卡片标题和筛选
        JPanel headerPanel = new JPanel(new BorderLayout());
        headerPanel.setOpaque(false);

        // 左侧标题
        JPanel titleContainer = new JPanel(new BorderLayout());
        titleContainer.setOpaque(false);

        JLabel titleLabel = new JLabel("历史预约记录");
        titleLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 18));
        titleLabel.setForeground(new Color(30, 41, 59));

        JLabel descLabel = new JLabel("前7天和明天的全部预约记录（不含今日）");
        descLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        descLabel.setForeground(new Color(100, 116, 139));

        titleContainer.add(titleLabel, BorderLayout.NORTH);
        titleContainer.add(descLabel, BorderLayout.CENTER);

        // 右侧筛选器
        JPanel filterPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0));
        filterPanel.setOpaque(false);

        JLabel filterLabel = new JLabel("状态筛选：");
        filterLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        filterLabel.setForeground(new Color(100, 116, 139));

        historyStatusFilter = new JComboBox<>(new String[] {
                "全部", "正常完成", "爽约", "早退", "进行中", "仅预约"
        });
        historyStatusFilter.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        historyStatusFilter.setPreferredSize(new Dimension(100, 28));

        // 添加筛选事件
        historyStatusFilter.addActionListener(e -> filterHistoryRecords());

        filterPanel.add(filterLabel);
        filterPanel.add(Box.createHorizontalStrut(5));
        filterPanel.add(historyStatusFilter);

        headerPanel.add(titleContainer, BorderLayout.WEST);
        headerPanel.add(filterPanel, BorderLayout.EAST);

        // 内容区域
        attendanceHistoryPanel.setOpaque(false);
        attendanceHistoryPanel.setLayout(new BoxLayout(attendanceHistoryPanel, BoxLayout.Y_AXIS));

        JScrollPane scrollPane = new JScrollPane(attendanceHistoryPanel);
        scrollPane.setBorder(BorderFactory.createEmptyBorder());
        scrollPane.setOpaque(false);
        scrollPane.getViewport().setOpaque(false);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

        card.add(headerPanel, BorderLayout.NORTH);
        card.add(scrollPane, BorderLayout.CENTER);

        return card;
    }

    private JPanel createModernCard() {
        JPanel card = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                // 背景渐变
                GradientPaint gradient = new GradientPaint(
                        0, 0, Color.WHITE,
                        0, getHeight(), new Color(252, 252, 255));
                g2d.setPaint(gradient);
                g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 16, 16);

                // 阴影
                g2d.setColor(new Color(0, 0, 0, 8));
                g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 16, 16);
            }
        };

        card.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));
        return card;
    }

    private void loadData() {
        loadTodayAttendance();
        loadAttendanceHistory();
    }

    private void loadTodayAttendance() {
        try {
            // 获取今天的所有预约记录
            todayRecords = attendanceController
                    .getUserTodayAllReservations(currentUser.getUserId());

            // 应用筛选并显示
            filterTodayRecords();

        } catch (Exception e) {
            e.printStackTrace();
            todayAttendancePanel.removeAll();
            JPanel errorPanel = createEmptyStatePanel("加载失败", "", new Color(239, 68, 68));
            todayAttendancePanel.add(errorPanel);
            todayAttendancePanel.revalidate();
            todayAttendancePanel.repaint();
        }
    }

    private void loadAttendanceHistory() {
        try {
            // 获取前七天和明天的所有预约记录（不包括今天）
            LocalDate today = LocalDate.now();
            LocalDate startDate = today.minusDays(7);
            LocalDate endDate = today.plusDays(1); // 包含明天

            // 获取所有记录然后过滤掉今天的
            List<AttendanceRecord> allRecords = attendanceController.getUserAllReservations(
                    currentUser.getUserId(), startDate, endDate);

            // 排除今天的记录
            historyRecords = allRecords.stream()
                    .filter(record -> !record.getReservationDate().equals(today))
                    .collect(Collectors.toList());

            // 应用筛选并显示
            filterHistoryRecords();

        } catch (Exception e) {
            e.printStackTrace();
            attendanceHistoryPanel.removeAll();
            JPanel errorPanel = createEmptyStatePanel("加载失败", "", new Color(239, 68, 68));
            attendanceHistoryPanel.add(errorPanel);
            attendanceHistoryPanel.revalidate();
            attendanceHistoryPanel.repaint();
        }
    }

    private JPanel createTodayAttendanceItem(AttendanceRecord record) {
        JPanel panel = new JPanel(new BorderLayout(15, 0)) {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                // 背景渐变
                GradientPaint gradient = new GradientPaint(
                        0, 0, Color.WHITE,
                        0, getHeight(), new Color(250, 252, 255));
                g2d.setPaint(gradient);
                g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 12, 12);

                // 细微的外边框
                g2d.setColor(new Color(220, 225, 235));
                g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 12, 12);
            }
        };

        panel.setOpaque(false);
        panel.setBorder(BorderFactory.createEmptyBorder(16, 20, 16, 20));
        panel.setPreferredSize(new Dimension(0, 80)); // 固定高度
        panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 80));

        // 左侧信息
        JPanel leftPanel = new JPanel(new BorderLayout());
        leftPanel.setOpaque(false);

        JLabel seatLabel = new JLabel(record.getSeat().getSeatNumber() + " · " + record.getSeat().getArea());
        seatLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
        seatLabel.setForeground(new Color(30, 41, 59));

        String timeText = record.getScheduledStartTime().format(DateTimeFormatter.ofPattern("HH:mm")) +
                " - " + record.getScheduledEndTime().format(DateTimeFormatter.ofPattern("HH:mm"));
        JLabel timeLabel = new JLabel(timeText + " · 今日");
        timeLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
        timeLabel.setForeground(new Color(107, 114, 128));

        leftPanel.add(seatLabel, BorderLayout.NORTH);
        leftPanel.add(timeLabel, BorderLayout.SOUTH);

        // 右侧操作区域
        JPanel rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 8, 0));
        rightPanel.setOpaque(false);

        ReservationStatus status = getReservationStatus(record);

        switch (status) {
            case NOT_STARTED:
                // 还未开始
                JLabel notStartedLabel = new JLabel("还未开始");
                notStartedLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
                notStartedLabel.setForeground(new Color(107, 114, 128));
                rightPanel.add(notStartedLabel);
                break;

            case CAN_CHECK_IN:
                // 可以签到
                JButton checkInBtn = new JButton("签到");
                styleActionButton(checkInBtn, new Color(34, 197, 94));
                checkInBtn.addActionListener(e -> handleCheckIn(record.getReservationId()));
                rightPanel.add(checkInBtn);
                break;

            case CHECKED_IN:
                // 已签到，可以签退
                JButton checkOutBtn = new JButton("签退");
                styleActionButton(checkOutBtn, new Color(239, 68, 68));
                checkOutBtn.addActionListener(e -> handleCheckOut(record.getReservationId()));
                rightPanel.add(checkOutBtn);

                JLabel checkedInLabel = new JLabel("已签到");
                checkedInLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
                checkedInLabel.setForeground(new Color(34, 197, 94));
                rightPanel.add(checkedInLabel);
                break;

            case OVERDUE:
                // 超时违规
                JLabel overdueLabel = new JLabel("违规");
                overdueLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
                overdueLabel.setForeground(new Color(239, 68, 68));
                rightPanel.add(overdueLabel);
                break;

            case COMPLETED:
                // 已完成
                JLabel completedLabel = new JLabel("已完成");
                completedLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
                completedLabel.setForeground(new Color(34, 197, 94));
                rightPanel.add(completedLabel);
                break;

            default:
                // 未知状态
                JLabel unknownLabel = new JLabel("未知");
                unknownLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 11));
                unknownLabel.setForeground(new Color(156, 163, 175));
                rightPanel.add(unknownLabel);
                break;
        }

        panel.add(leftPanel, BorderLayout.CENTER);
        panel.add(rightPanel, BorderLayout.EAST);

        return panel;
    }

    private JPanel createHistoryAttendanceItem(AttendanceRecord record) {
        JPanel panel = new JPanel(new BorderLayout(12, 0)) {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

                // 背景渐变
                GradientPaint gradient = new GradientPaint(
                        0, 0, Color.WHITE,
                        0, getHeight(), new Color(248, 252, 255));
                g2d.setPaint(gradient);
                g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10);

                // 细微的外边框
                g2d.setColor(new Color(220, 225, 235));
                g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 10, 10);
            }
        };

        panel.setOpaque(false);
        panel.setBorder(BorderFactory.createEmptyBorder(12, 16, 12, 16));
        panel.setPreferredSize(new Dimension(0, 65)); // 固定高度（比今日考勤稍小）
        panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 65));

        // 左侧信息
        JPanel leftPanel = new JPanel(new BorderLayout());
        leftPanel.setOpaque(false);

        // 位置 + 日期信息（同一行显示）
        String seatAndDateInfo = record.getSeat().getSeatNumber() + " · " + record.getSeat().getArea() +
                " · " + record.getReservationDate().format(DateTimeFormatter.ofPattern("MM-dd")) +
                " (" + getRelativeDateText(record.getReservationDate()) + ")";

        JLabel seatLabel = new JLabel(seatAndDateInfo);
        seatLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 13));
        seatLabel.setForeground(new Color(75, 85, 99));

        String timeText = record.getScheduledStartTime().format(DateTimeFormatter.ofPattern("HH:mm")) +
                "-" + record.getScheduledEndTime().format(DateTimeFormatter.ofPattern("HH:mm"));

        if (record.getActualDuration() > 0) {
            timeText += " (" + record.getActualDuration() + "分钟)";
        }

        JLabel timeLabel = new JLabel(timeText);
        timeLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 13));
        timeLabel.setForeground(new Color(107, 114, 128));

        leftPanel.add(seatLabel, BorderLayout.NORTH);
        leftPanel.add(timeLabel, BorderLayout.SOUTH);

        // 右侧状态
        String statusText;
        Color statusColor;

        switch (record.getAttendanceStatus()) {
            case 1:
                statusText = "正常完成";
                statusColor = new Color(34, 197, 94);
                break;
            case 2:
                statusText = "爽约";
                statusColor = new Color(239, 68, 68);
                break;
            case 3:
                statusText = "早退";
                statusColor = new Color(245, 158, 11);
                break;
            case 0:
                statusText = "进行中";
                statusColor = new Color(59, 130, 246);
                break;
            case -1:
                statusText = "仅预约";
                statusColor = new Color(156, 163, 175);
                break;
            default:
                statusText = "未知";
                statusColor = new Color(107, 114, 128);
        }

        JLabel statusLabel = new JLabel(statusText);
        statusLabel.setFont(new Font("Microsoft YaHei", Font.BOLD, 11));
        statusLabel.setForeground(statusColor);

        panel.add(leftPanel, BorderLayout.CENTER);
        panel.add(statusLabel, BorderLayout.EAST);

        return panel;
    }

    private JPanel createEmptyStatePanel(String message, String icon, Color color) {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setOpaque(false);
        panel.setBorder(BorderFactory.createEmptyBorder(40, 20, 40, 20));

        JLabel iconLabel = new JLabel(icon, SwingConstants.CENTER);
        iconLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 32));
        iconLabel.setForeground(color);

        JLabel messageLabel = new JLabel(message, SwingConstants.CENTER);
        messageLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 14));
        messageLabel.setForeground(color);

        JPanel centerPanel = new JPanel(new BorderLayout(0, 10));
        centerPanel.setOpaque(false);
        centerPanel.add(iconLabel, BorderLayout.NORTH);
        centerPanel.add(messageLabel, BorderLayout.CENTER);

        panel.add(centerPanel, BorderLayout.CENTER);
        return panel;
    }

    private void handleCheckIn(int reservationId) {
        try {
            CheckInResult result = attendanceController.checkIn(reservationId, currentUser.getUserId());

            if (result.isSuccess()) {
                JOptionPane.showMessageDialog(this, result.getMessage(), "签到成功", JOptionPane.INFORMATION_MESSAGE);
                loadTodayAttendance();
            } else {
                JOptionPane.showMessageDialog(this, result.getMessage(), "签到失败", JOptionPane.WARNING_MESSAGE);
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "签到操作失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void handleCheckOut(int reservationId) {
        try {
            CheckOutResult result = attendanceController.checkOut(reservationId, currentUser.getUserId());

            if (result.isSuccess()) {
                JOptionPane.showMessageDialog(this, result.getMessage(), "签退成功", JOptionPane.INFORMATION_MESSAGE);
                loadTodayAttendance();
                loadAttendanceHistory(); // 签退后更新历史记录
            } else {
                JOptionPane.showMessageDialog(this, result.getMessage(), "签退失败", JOptionPane.WARNING_MESSAGE);
            }
        } catch (Exception e) {
            JOptionPane.showMessageDialog(this, "签退操作失败: " + e.getMessage(), "错误", JOptionPane.ERROR_MESSAGE);
        }
    }

    private void styleModernButton(JButton button, Color backgroundColor) {
        button.setPreferredSize(new Dimension(100, 38));
        button.setBackground(backgroundColor);
        button.setForeground(Color.WHITE);
        button.setFont(new Font("Microsoft YaHei", Font.BOLD, 14));
        button.setBorder(BorderFactory.createEmptyBorder(10, 20, 10, 20));
        button.setFocusPainted(false);
        button.setCursor(new Cursor(Cursor.HAND_CURSOR));

        // 悬停效果
        button.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                if (button.isEnabled()) {
                    button.setBackground(backgroundColor.darker());
                }
            }

            @Override
            public void mouseExited(java.awt.event.MouseEvent evt) {
                if (button.isEnabled()) {
                    button.setBackground(backgroundColor);
                }
            }
        });
    }

    private void styleActionButton(JButton button, Color backgroundColor) {
        button.setPreferredSize(new Dimension(60, 28));
        button.setBackground(backgroundColor);
        button.setForeground(Color.WHITE);
        button.setFont(new Font("Microsoft YaHei", Font.BOLD, 12));
        button.setBorder(BorderFactory.createEmptyBorder(6, 12, 6, 12));
        button.setFocusPainted(false);
        button.setCursor(new Cursor(Cursor.HAND_CURSOR));

        // 悬停效果
        button.addMouseListener(new java.awt.event.MouseAdapter() {
            @Override
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                if (button.isEnabled()) {
                    button.setBackground(backgroundColor.darker());
                }
            }

            @Override
            public void mouseExited(java.awt.event.MouseEvent evt) {
                if (button.isEnabled()) {
                    button.setBackground(backgroundColor);
                }
            }
        });
    }

    /**
     * 获取预约状态
     */
    private ReservationStatus getReservationStatus(AttendanceRecord record) {
        LocalDate today = LocalDate.now();
        LocalTime now = LocalTime.now();

        // 如果不是今天的预约，返回未知状态
        if (!record.getReservationDate().equals(today)) {
            return ReservationStatus.UNKNOWN;
        }

        LocalTime startTime = record.getScheduledStartTime();
        LocalTime endTime = record.getScheduledEndTime();

        // 计算签到时间窗口：开始前5分钟到开始后30分钟
        LocalTime checkInStart = startTime.minusMinutes(5);
        LocalTime checkInEnd = startTime.plusMinutes(30);

        // 已签退完成
        if (record.isCheckedOut()) {
            return ReservationStatus.COMPLETED;
        }

        // 已签到但未签退
        if (record.isCheckedIn()) {
            return ReservationStatus.CHECKED_IN;
        }

        // 未签到的情况
        if (now.isBefore(checkInStart)) {
            // 还未到签到时间
            return ReservationStatus.NOT_STARTED;
        } else if (now.isAfter(endTime)) {
            // 已超过预约结束时间，真正的违规
            return ReservationStatus.OVERDUE;
        } else {
            // 在预约时间段内都可以签到（包括超过30分钟的情况）
            return ReservationStatus.CAN_CHECK_IN;
        }
    }

    /**
     * 预约状态枚举
     */
    private enum ReservationStatus {
        NOT_STARTED, // 还未开始
        CAN_CHECK_IN, // 可以签到
        CHECKED_IN, // 已签到
        COMPLETED, // 已完成
        OVERDUE, // 超时违规
        UNKNOWN // 未知状态
    }

    /**
     * 筛选今日记录
     */
    private void filterTodayRecords() {
        todayAttendancePanel.removeAll();

        if (todayRecords == null || todayRecords.isEmpty()) {
            JPanel emptyPanel = createEmptyStatePanel("今日暂无预约", "📅", new Color(156, 163, 175));
            todayAttendancePanel.add(emptyPanel);
        } else {
            String selectedStatus = (String) todayStatusFilter.getSelectedItem();
            List<AttendanceRecord> filteredRecords = new ArrayList<>();

            for (AttendanceRecord record : todayRecords) {
                if (shouldShowRecord(record, selectedStatus, true)) {
                    filteredRecords.add(record);
                }
            }

            if (filteredRecords.isEmpty()) {
                JPanel emptyPanel = createEmptyStatePanel("没有符合条件的记录", "🔍", new Color(156, 163, 175));
                todayAttendancePanel.add(emptyPanel);
            } else {
                for (int i = 0; i < filteredRecords.size(); i++) {
                    AttendanceRecord record = filteredRecords.get(i);
                    JPanel recordPanel = createTodayAttendanceItem(record);
                    recordPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
                    todayAttendancePanel.add(recordPanel);

                    // 添加间距（除了最后一个）
                    if (i < filteredRecords.size() - 1) {
                        todayAttendancePanel.add(Box.createVerticalStrut(12));
                    }
                }
            }
        }

        todayAttendancePanel.revalidate();
        todayAttendancePanel.repaint();
    }

    /**
     * 筛选历史记录
     */
    private void filterHistoryRecords() {
        attendanceHistoryPanel.removeAll();

        if (historyRecords == null || historyRecords.isEmpty()) {
            JPanel emptyPanel = createEmptyStatePanel("暂无预约记录", "📚", new Color(156, 163, 175));
            attendanceHistoryPanel.add(emptyPanel);
        } else {
            String selectedStatus = (String) historyStatusFilter.getSelectedItem();
            List<AttendanceRecord> filteredRecords = new ArrayList<>();

            for (AttendanceRecord record : historyRecords) {
                if (shouldShowRecord(record, selectedStatus, false)) {
                    filteredRecords.add(record);
                }
            }

            if (filteredRecords.isEmpty()) {
                JPanel emptyPanel = createEmptyStatePanel("没有符合条件的记录", "🔍", new Color(156, 163, 175));
                attendanceHistoryPanel.add(emptyPanel);
            } else {
                // 限制显示数量为15条
                List<AttendanceRecord> displayRecords = filteredRecords.subList(0,
                        Math.min(filteredRecords.size(), 15));
                for (int i = 0; i < displayRecords.size(); i++) {
                    AttendanceRecord record = displayRecords.get(i);
                    JPanel recordPanel = createHistoryAttendanceItem(record);
                    recordPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
                    attendanceHistoryPanel.add(recordPanel);

                    // 添加间距（除了最后一个）
                    if (i < displayRecords.size() - 1) {
                        attendanceHistoryPanel.add(Box.createVerticalStrut(10));
                    }
                }

                // 如果有更多记录，显示提示
                if (filteredRecords.size() > 15) {
                    JLabel moreLabel = new JLabel("... 还有 " + (filteredRecords.size() - 15) + " 条记录",
                            SwingConstants.CENTER);
                    moreLabel.setFont(new Font("Microsoft YaHei", Font.PLAIN, 12));
                    moreLabel.setForeground(new Color(156, 163, 175));
                    moreLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));
                    attendanceHistoryPanel.add(moreLabel);
                }
            }
        }

        attendanceHistoryPanel.revalidate();
        attendanceHistoryPanel.repaint();
    }

    /**
     * 判断记录是否符合筛选条件
     */
    private boolean shouldShowRecord(AttendanceRecord record, String filterStatus, boolean isToday) {
        if ("全部".equals(filterStatus)) {
            return true;
        }

        if (isToday) {
            // 今日记录的筛选逻辑
            ReservationStatus status = getReservationStatus(record);
            switch (filterStatus) {
                case "待签到":
                    return status == ReservationStatus.CAN_CHECK_IN;
                case "已签到":
                    return status == ReservationStatus.CHECKED_IN;
                case "已完成":
                    return status == ReservationStatus.COMPLETED;
                case "超时违规":
                    return status == ReservationStatus.OVERDUE;
                case "未开始":
                    return status == ReservationStatus.NOT_STARTED;
                default:
                    return true;
            }
        } else {
            // 历史记录的筛选逻辑
            switch (filterStatus) {
                case "正常完成":
                    return record.getAttendanceStatus() == 1;
                case "爽约":
                    return record.getAttendanceStatus() == 2;
                case "早退":
                    return record.getAttendanceStatus() == 3;
                case "进行中":
                    return record.getAttendanceStatus() == 0;
                case "仅预约":
                    return record.getAttendanceStatus() == -1; // 没有考勤记录
                default:
                    return true;
            }
        }
    }

    /**
     * 获取相对日期文本（明天、一天前、两天前等）
     */
    private String getRelativeDateText(LocalDate date) {
        LocalDate today = LocalDate.now();
        long daysDiff = java.time.temporal.ChronoUnit.DAYS.between(today, date);

        if (daysDiff == 0) {
            return "今天";
        } else if (daysDiff == 1) {
            return "明天";
        } else if (daysDiff == -1) {
            return "昨天";
        } else if (daysDiff > 0) {
            return daysDiff + "天后";
        } else {
            return Math.abs(daysDiff) + "天前";
        }
    }
}
